/*
* @Author: Adolphus.Yao
* @Date:   2019-08-23 12:26:53
* @Last Modified by:   Adolphus.Yao
* @Last Modified time: 2019-08-27 20:58:42
*/

package main

import (
    "bytes"
    "crypto/des"
    "errors"
    "log"
)

func main() {//7d630f3a8130d7338f5e77a0ca01fa8d
    log.SetFlags(log.LstdFlags | log.Lshortfile)
    log.Println("程序开始....")
    key := []byte("lRr7SQts")
    data := []byte("18011959171")

    out, _ := MyEncrypt(data, key)
    log.Printf("加密后:%x\n", out)
    out, _ = MyDecrypt(out, key)
    log.Println("解密后:", string(out))
}
func MyEncrypt(data, key []byte) ([]byte, error) {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil, err
    }
    bs := block.BlockSize()
    data = PKCS5Padding(data, bs)
    if len(data)%bs != 0 {
        return nil, errors.New("Need a multiple of the blocksize")
    }
    out := make([]byte, len(data))
    dst := out
    for len(data) > 0 {
        block.Encrypt(dst, data[:bs])
        data = data[bs:]
        dst = dst[bs:]
    }
    return out, nil
}
func MyDecrypt(data []byte, key []byte) ([]byte, error) {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil, err
    }
    bs := block.BlockSize()
    if len(data)%bs != 0 {
        return nil, errors.New("crypto/cipher: input not full blocks")
    }
    out := make([]byte, len(data))
    dst := out
    for len(data) > 0 {
        block.Decrypt(dst, data[:bs])
        data = data[bs:]
        dst = dst[bs:]
    }
    out = PKCS5UnPadding(out)
    return out, nil
}

func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
    padding := blockSize - len(ciphertext)%blockSize
    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(ciphertext, padtext...)
}

func PKCS5UnPadding(origData []byte) []byte {
    length := len(origData)
    unpadding := int(origData[length-1])
    return origData[:(length - unpadding)]
}